﻿// <copyright file="BlogController.cs" company="Clever Software">
// Copyright (c) 2013, 2014 All Right Reserved, http://www.cleversoftware.by
//
// This source is subject to the Microsoft Permissive License.
// Please see the License.txt file for more information.
// All other rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// </copyright>
// <author>Clever Software</author>
// <email>info@cleversoftware.by</email>
// <date>2014-02-04</date> 
// <summary>CleverCMS source code</summary>

namespace CleverCMS.Web.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;

    using PagedList;


    using Blog.Data.Entities;
    using Core.Extensions;
    using Blog.Services;
    using Blog.Services.ViewModels;
    
    public class BlogController : Controller
    {
        private const int ENTRIESPERPAGE = 2;
        private readonly BlogEntryService m_blogService;

        public BlogController(BlogEntryService blogService)
        {
            this.m_blogService = blogService;
        }

        public virtual ActionResult Index(string category, string search, int? page, string tag )
        {
            var entries = m_blogService.GetAll(Request.IsAuthenticated && User.IsInRole("Admin"),
                                                tag,
                                                search,
                                                category);

            var model = new IndexModel
            {
                Entries = entries.ToPagedList(page.HasValue ? page.Value : 1, ENTRIESPERPAGE),
                CurrentPage = page ?? 1,
                Tag = tag,
                Search = search,
                CategoryID = category,
                Categories = m_blogService.GetAllCategories(),
                LatesBlog = m_blogService.GetLatesBlog(),
                Tags = m_blogService.GetAllTags(),
                Dates = m_blogService.GetAllDates()
            };

            ViewBag.IsArchive = false;
            return View(model);
        }

        public virtual ActionResult Archive(int month, int year, string category, int? page)
        {
            var entries = m_blogService.GetForArchive(month, year, category);
            var model = new IndexModel
            {
                Entries = entries.ToPagedList(page.HasValue ? page.Value : 1, ENTRIESPERPAGE),
                CurrentPage =   page ?? 1,
                CategoryID =    category,
                Categories =    m_blogService.GetAllCategories(),
                LatesBlog =     m_blogService.GetLatesBlog(),
                Tags =          m_blogService.GetAllTags(),
                Dates =         m_blogService.GetAllDates()
            };

            ViewBag.IsArchive = true;
            return View("index",model);
        }

        public virtual ActionResult Entry(string cat, string id)
        {
            var entry = m_blogService.GetByUrl(Request.IsAuthenticated && User.IsInRole("Admin"), id);
             
            if (entry == null)
                throw new HttpException(404, "Not Found");

            if (!ModelState.IsValid)
            {
                var errorModel = new BlogEntryModel
                {
                    BlogEntry = entry
                };
                return View(errorModel);
            }

            m_blogService.AddViewCount(entry);
            var blogEntry = new BlogEntryModel()
            {
                BlogEntry = entry,
                HideNewCommentsForm = true
            };

            var model = new IndexModel
            {
                Entry = blogEntry,
                Categories =    m_blogService.GetAllCategories(),
                LatesBlog =     m_blogService.GetLatesBlog(),
                Tags =          m_blogService.GetAllTags(),
                Rating =        ConvertToRatingViewModel(m_blogService.GetRating(entry.Id), entry.Id),
                Comments =      new BlogCommentsViewModel
                                                        {
                                                            Id = blogEntry.Id,
                                                            HideNewCommentsForm = false,
                                                            Comments = blogEntry.Comments
                                                        },
                Dates =         m_blogService.GetAllDates()
            };
            
            return View(model);
        }

        // TODO: Rework Rating converters 2
        #region Rating converters for blog post
        private static BlogRatingViewModel ConvertToRatingViewModel(IEnumerable<BlogEntryRating> ratings, int objectId)
        {
            if (ratings != null && ratings.Any())
            {
                int count = ratings.Count();
                double avg = ratings.Sum(cmsRating => cmsRating.Rating) / count;
                return new BlogRatingViewModel { AverageRating = ConvertDoubleToFixed(avg), TotalRaters = count, IsPage = false, Id = objectId };
            }
            else
            {
                return new BlogRatingViewModel { AverageRating = 0, TotalRaters = 0, IsPage = false, Id = objectId };
            }
        }
        private static double ConvertDoubleToFixed(double from)
        {
            double cel = Math.Truncate(from);
            double ost = from - cel;
            double del = Math.Truncate(ost / 0.25);
            return cel + (del + (ost % 0.25 > 0.125 ? 1 : 0)) * 0.25;
        }
        #endregion

        #region Comments

        [HttpPost]
        public JsonResult AddComment(int entryId, string name, string email, string comment, int? replyId)
        {
            if (name != null)
            {
                var newComment = new BlogEntryComment
                {
                    BlogEntryId = entryId,
                    Name = name,
                    Email = email,
                    Comment = comment,
                    ParentId = replyId
                };

                m_blogService.AddComment(newComment);
                return Json(new { result = true, id = newComment.Id, hash = newComment.Email.ToLowerInvariant().EncryptMD5().ToLowerInvariant()});
            }
            return Json(new { result = false });
        }

        [HttpPost]
        public JsonResult GetName(int id)
        {
            BlogEntryComment comment = m_blogService.GetCommentsById(id).First();
            var name = comment.Name;
            return Json(name, JsonRequestBehavior.AllowGet);
        }

        #endregion
    }
}